package tolietdemo.lock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

//租客类，客户类
class Customer implements Runnable {

    private Toliet toliet;
    private Lock lock;

    public Customer(Toliet toliet) {
        this.toliet = toliet;
        lock = new ReentrantLock();
    }

    @Override
    public void run() {
        //开始来描述这个故事....
        //怎么写呢？
        try {
            //2秒钟内，尝试获得锁。
            if (lock.tryLock(2, TimeUnit.SECONDS)) {
                //判断一下是否是小张的线程
                if ("小张".equals(Thread.currentThread().getName())) {
                    toliet.xuxu();
                    //释放锁。
                    //注意：释放的不是卫生间的锁。toliet.wait();
                    lock.unlock();
                    //把休眠动作，一定要放到unlock之后，unlock不是阻塞
                    //为了在unlock之后，运行CPU时间片切换到其它线程。
                    Thread.sleep(50);
                    if (lock.tryLock(5, TimeUnit.SECONDS)) {
                        //又获得了锁。
                        toliet.brushTeeth();//刷牙
                        lock.unlock();
                    }
                } else {
                    toliet.xuxu();
                    lock.unlock();
                    Thread.sleep(50);
                    if (lock.tryLock(5, TimeUnit.SECONDS)) {
                        //又获得了锁。
                        toliet.brushTeeth();//刷牙
                        lock.unlock();
                    }
                }
            }

        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}


//卫生间类
class Toliet {
    //定义两个方法。
    //解小便的方法...
    public void xuxu() {
        System.out.println(Thread.currentThread().getName() + "正在卫生间嘘嘘...");
    }

    //刷牙
    public void brushTeeth() {
        System.out.println(Thread.currentThread().getName() + "正在卫生间刷牙...");
    }
}

public class TolietDemo {

    public static void main(String[] args) {

        Toliet toliet = new Toliet();
        Customer c = new Customer(toliet);
        Thread zhangThread = new Thread(c, "小张");
        Thread liThread = new Thread(c, "小李");

        //小张先起床，意味：小张线程先执行。
        //如何保证小张线程先执行呢。
        zhangThread.start();
        //采用卑鄙无耻的手段。
        try {
            Thread.sleep(50);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        liThread.start();
    }
}
